﻿using Core.CommandProcesser;
using Core.Enums;
using System.Collections.Generic;

namespace Core.Entities
{
    /// <summary> 命令信息类 </summary>
    public class CommandInfo
    {
        /// <summary>
        /// 初始化命令信息
        /// </summary>
        /// <param name="Name">命令名称</param>
        public CommandInfo(string Name)
        { 
            this.Name = Name;

            Caches = new Dictionary<object[], CommandCacheInfo>(0, FieldsComparer.Instance);

            CachesLock = new object();
        }

        /// <summary> 命令 Id </summary>
        public int Id;
        /// <summary> 命令名称 </summary>
        public string Name;
        /// <summary> 命令类型 </summary>
        public string Type;
        /// <summary> 命令代码 </summary>
        public string Code;
        /// <summary> 命令标识 </summary>
        public CommandSigns Sign;
        /// <summary> 命令说明 </summary>
        public string Description;
        /// <summary> 命令参数 </summary>
        public CommandParamInfo[] Params;
        /// <summary> 命令返回值 </summary>
        public CommandParamInfo[] Results;
        /// <summary> 缓存关联名称 </summary>
        public string CacheToken;

        /// <summary> 命令处理器辅助参数 </summary>
        internal object InternalTag;
        /// <summary> 命令处理器 </summary>
        internal BaseCommandProcesser InternalProcesser;
        /// <summary> 命令字段验证器 </summary>
        internal CommandFieldVerifier[] InternalValidations;
        /// <summary> 前置触发器 </summary>
        internal CommandInfo[] BeforeTriggers;
        /// <summary> 后置触发器 </summary>
        internal CommandInfo[] AfterTriggers;
        /// <summary> 该命令的缓存集合 </summary>
        internal Dictionary<object[], CommandCacheInfo> Caches;
        /// <summary> 缓存集合锁 </summary>
        internal object CachesLock;
        /// <summary> 与此更新命令的 CacheToken 相同的读取命令集合。 </summary>
        internal CommandInfo[] SimilarCacheCommands;
        /// <summary> 缓存关联名称集合 </summary>
        internal string[] CacheTokens;
    }

    /// <summary>
    /// 缓存的参数比较器
    /// </summary>
    public sealed class FieldsComparer : IEqualityComparer<object[]>
    {
        /// <summary>
        /// 单例模式
        /// </summary>
        public static readonly FieldsComparer Instance = new FieldsComparer();

        private FieldsComparer()
        {

        }

        /// <summary>
        /// 比较两个参数的值是否一致
        /// </summary>
        /// <param name="x">a 参数</param>
        /// <param name="y">b 参数</param>
        /// <returns>返回一个 bool 值。</returns>
        public bool Equals(object[] x, object[] y)
        {
            if (x.Length != y.Length)
            {
                return false;
            }

            for (int i = 0; i < x.Length; i++)
            {
                if (x[i] == null)
                {
                    if (y[i] != null)
                    {
                        return false;
                    }
                }
                else if (!x[i].Equals(y[i]))
                {
                    return false;
                }
            }

            return true;
        }

        /// <summary>
        /// 获得此参数的 Hash 值。
        /// </summary>
        /// <param name="obj">参数</param>
        /// <returns>返回一个 Hash 值。</returns>
        public int GetHashCode(object[] obj)
        {
            int Result = 0;

            for (int i = 0; i < obj.Length; i++)
            {
                Result ^= obj[i].GetHashCode();
            }

            return Result;
        }
    }

    /// <summary>
    /// 命令参数信息
    /// </summary>
    public class CommandParamInfo
    {
        /// <summary>
        /// 参数名
        /// </summary>
        public string Name;
        /// <summary>
        /// 参数类型
        /// </summary>
        public ParamTypes Type;
        /// <summary>
        /// 参数标识
        /// </summary>
        public CommandParamSigns Sign;
        /// <summary>
        /// 参数说明
        /// </summary>
        public string Description;
    }

    /// <summary>
    /// 命令参数标识符
    /// </summary>
    public enum CommandParamSigns
    {
        /// <summary>
        /// 允许为 Null
        /// </summary>
        AllowNull = 0x1,
        /// <summary>
        /// 系统基带参数，不需要用户传入
        /// </summary>
        SystemParam = 0x2
    }

    /// <summary>
    /// 命令标识符
    /// </summary>
    public enum CommandSigns : int
    {
        /// <summary> 表示这条 Sql 语句是 Select 语句 </summary>
        Select = 0x1,
        /// <summary> 表示这条 Sql 语句是 Insert 语句 </summary>
        Insert = 0x2,
        /// <summary> 表示这条 Sql 语句是 Update 语句 </summary>
        Update = 0x4,
        /// <summary> 表示这条 Sql 语句是 Delete 语句 </summary>
        Delete = 0x8,
        /// <summary> 表示这个命令要求授权 </summary>
        Authorize = 0x10,
        /// <summary> 表示这条命令不能被用户调用 </summary>
        NoCall = 0x20,
        /// <summary> 表示这条 Select 语句返回单行数据 </summary>
        SingleObjectResult = 0x40,
        /// <summary> 触发器命令 </summary>
        Trigger = 0x80,
        /// <summary> 使用内存缓存 </summary>
        MemoryCache = 0x100,
        /// <summary> 使用磁盘缓存 </summary>
        DiskCache = 0x200,
        /// <summary> 表示该命令使用缓存 用于 & 运算符 </summary>
        UseCache = MemoryCache | DiskCache
    }

    /// <summary>
    /// 命令字段验证器
    /// </summary>
    public class CommandFieldVerifier
    {
        public CommandFieldVerifier(string Name, string Mode, string Value, string Description)
        {

        }
    }
}